home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
video
/
fly8111-.000
/
fly8111-
/
fly8
/
ptrmgr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1979-12-31
|
10KB
|
585 lines
/* --------------------------------- ptrmgr.c ------------------------------- */
/* This is part of the flight simulator 'fly8'.
* Author: Eyal Lebedinsky (eyal@ise.canberra.edu.au).
*/
/* Pointing devices manager.
*/
#include "fly.h"
LOCAL_FUNC void NEAR get_btns (POINTER *p, char *options);
extern int FAR
pointers_init (void)
{return (0);}
extern void FAR
pointers_term (void)
{}
static int def_opt[NOPTS] = {
1, /* +ve x */
0, /* x axis is channel 0 */
1, /* +ve y */
1 /* y axis is channel 1 */
};
extern POINTER * FAR
pointer_select (char *name)
{
int l, n;
char *options;
int opt[NOPTS];
POINTER *ptr;
struct PtrDriver NEAR* FAR* p;
memcpy (opt, def_opt, sizeof (opt));
if (!name) {
p = PtrDrivers; /* use default */
options = "";
goto ret;
}
options = strchr (name, ':');
if (options) { /* ":+x+y" */
n = options - name; /* name length */
++options;
l = strlen (options); /* options length */
if (l >= 1) {
if (options[0] == '-') /* x direction */
opt[0] = -1;
else if (options[0] == '+')
opt[0] = 1;
else
return (0);
}
if (l >= 2) {
if (options[1] == 'x') /* x select */
opt[1] = 0;
else if (options[1] == 'y')
opt[1] = 1;
else
return (0);
}
if (l >= 3) {
if (options[2] == '-') /* y direction */
opt[2] = -1;
else if (options[2] == '+')
opt[2] = 1;
else
return (0);
}
if (l >= 4) {
if (options[3] == 'x') /* y select */
opt[3] = 0;
else if (options[3] == 'y')
opt[3] = 1;
else
return (0);
if (opt[1] == opt[3]) /* exclusive */
return (0);
}
} else
n = strlen (name);
for (p = PtrDrivers; *p; ++p) {
if (!strnicmp ((*p)->name, name, n) && !(*p)->name[n])
break;
}
ret:
if (!*p)
return (0);
if (!NEW (ptr))
return (0);
ptr->control = *p;
ptr->name = (*p)->name;
memcpy (ptr->opt, opt, sizeof (ptr->opt));
get_btns (ptr, options);
if (ptr->control->Init (ptr, options))
DEL0 (ptr);
return (ptr);
}
extern POINTER * FAR
pointer_release (POINTER *ptr)
{
ptr->control->Term (ptr);
DEL (ptr);
return (0);
}
extern void FAR
std_key (POINTER *p, int key)
{
int i;
switch (key) {
case KF_POWER_AB:
if (p->l[3] < 75)
p->l[3] = 75; /* full power first */
else {
p->l[3] += 5;
if (p->l[3] > 100)
p->l[3] = 100;
}
break;
case KF_POWER_UP:
i = (p->l[3] > 75) ? 100 : 75;
p->l[3] += 5;
if (p->l[3] > i)
p->l[3] = i;
break;
case KF_POWER_DOWN:
p->l[3] -= 5;
if (p->l[3] < 0)
p->l[3] = 0;
break;
case KF_POWER_0:
p->l[3] = 0;
break;
case KF_POWER_100:
p->l[3] = 75;
break;
case KF_LEVEL:
++p->b[0];
break;
case KF_ORIGIN:
++p->b[1];
break;
case KF_FIRE:
++p->b[2];
break;
case KF_RESET_ROLL:
++p->b[4];
break;
case KF_STABLE:
++p->b[3];
break;
case KF_FRUDLEFT: /* rudder left */
p->l[2] += 10;
if (p->l[2] > 100)
p->l[2] = 100;
break;
case KF_FRUDRITE: /* rudder right */
p->l[2] -= 10;
if (p->l[2] < -100)
p->l[2] = -100;
break;
case KF_FRUDCNTR: /* rudder center */
p->l[2] = 0;
break;
case ']': /* flaps: more */
p->l[6] += 10;
if (p->l[6] > 100)
p->l[6] = 100;
break;
case '[': /* flaps: less */
p->l[6] -= 10;
if (p->l[6] < 0)
p->l[6] = 0;
break;
case '}': /* spoilers: more */
p->l[7] += 10;
if (p->l[7] > 100)
p->l[7] = 100;
break;
case '{': /* spoilers: less */
p->l[7] -= 10;
if (p->l[7] < 0)
p->l[7] = 0;
break;
case ')': /* wheel brakes: more */
p->l[9] += 10;
if (p->l[9] > 100)
p->l[9] = 100;
break;
case '(': /* wheel brakes: less */
p->l[9] -= 10;
if (p->l[9] < 0)
p->l[9] = 0;
break;
case '>': /* speed brakes: more */
p->l[8] += 25;
if (p->l[8] > 100)
p->l[8] = 100;
break;
case '<': /* speed brakes: less */
p->l[8] -= 25;
if (p->l[8] < 0)
p->l[8] = 0;
break;
case '+': /* speed brakes on/off */
if (p->l[8])
p->l[8] = 0;
else
p->l[8] = 100;
break;
case 'b': /* wheels brakes on/off */
if (p->l[9])
p->l[9] = 0;
else
p->l[9] = 100;
break;
case 'g':
++p->b[5]; /* landing gear up/down */
break;
case ' ':
++p->b[6]; /* release radar lock */
break;
/* Ctl Arrows used for trim.
*/
case KF_ZRIGHT: /* trim: right */
++p->l[4];
if (p->l[4] > 100)
p->l[4] = 100;
break;
case KF_ZLEFT: /* trim: left */
--p->l[4];
if (p->l[4] < -100)
p->l[4] = -100;
break;
case KF_ZUP: /* trim: nose down */
--p->l[5];
if (p->l[5] < -100)
p->l[5] = -100;
break;
case KF_ZDOWN: /* trim: nose up */
++p->l[5];
if (p->l[5] > 100)
p->l[5] = 100;
break;
case '\\': /* trim: reset */
p->l[4] = p->l[5] = 0;
break;
}
}
/* Select Pointing Device
*/
extern int FAR
menu_ptrs (void)
{
MENU *MenuPtr;
int sel, i, nEntries, EntrySize;
char *oldptr, newptr[256], *p;
POINTER *ptr;
for (nEntries = 0; PtrDrivers[nEntries]; ++nEntries)
;
;
EntrySize = 20;
if (!(MenuPtr = (MENU *) memory_calloc (nEntries+1,
sizeof (*MenuPtr))))
return (1);
sel = MENU_FAILED;
for (i = 0; i < nEntries; ++i)
if (!(MenuPtr[i].text = (char *) memory_alloc (EntrySize)))
goto ret;
oldptr = st.ptrname;
sel = 0;
for (i = 0; i < nEntries; ++i) {
MenuPtr[i].letter = (Uchar)menuch[i];
strcpy (MenuPtr[i].text, PtrDrivers[i]->name);
if (!stricmp (PtrDrivers[i]->name, oldptr))
sel = i;
}
sel = menu_open (MenuPtr, sel);
oldptr = st.ptrname;
switch (sel) {
case MENU_ABORTED:
case MENU_FAILED:
break;
default:
strcpy (newptr, PtrDrivers[sel]->name);
strcat (newptr, ":");
i = strlen (newptr);
if (NULL != (p = strchr (oldptr, ':')))
strcpy (newptr+i, p+1);
edit_str ("pointer options:", newptr + i, sizeof (newptr) - i);
sim_set ();
if (T(ptr = CV->pointer))
CV->pointer = pointer_release (ptr);
for (;;) {
if (T(ptr = pointer_select (newptr))) {
CV->pointer = ptr;
st.ptrname = STRfree (st.ptrname);
st.ptrname = STRdup (newptr);
break;
}
MsgEPrintf (-100, "pointer init failed");
if (T(ptr = pointer_select (oldptr))) {
CV->pointer = ptr;
break;
}
MsgEPrintf (-100, "old pointer init failed");
if (oldptr) {
if (T(ptr = pointer_select (NULL))) {
CV->pointer = ptr;
st.ptrname = STRfree (st.ptrname);
st.ptrname = STRdup (ptr->name);
break;
}
}
LogPrintf ("default pointer init failed\n");
die ();
}
sim_reset ();
break;
}
ret:
for (i = 0; i < nEntries; ++i)
if (MenuPtr[i].text)
memory_free (MenuPtr[i].text, EntrySize);
MenuPtr = memory_cfree (MenuPtr, nEntries+1, sizeof (*MenuPtr));
if (MENU_FAILED == sel)
return (1);
menu_close ();
return (0);
}
/* From here on: buttons stuff.
*/
#define BTN_POSITION 0x0001
#define BTN_DEBOUNCE 0x0080
LOCAL_FUNC void NEAR
get_btn (POINTER *p, char *options, char *opt, Ushort mode)
{
char *s;
int n;
int prev;
int quit;
if (F(s = get_arg (options, opt)))
return;
for (prev = 0, quit = 0; !quit;) {
if ('-' == (n = *s++)) {
if ((n = opt36 (*s++)) < 0) {
quit = 1;
n = rangeof (p->btn) - 1;
}
while (prev <= n)
p->btn[prev++] |= mode;
} else if ((n = opt36 (n)) >= 0)
p->btn[n] |= mode;
else
quit = 1;
prev = n;
}
}
/* read button debounce definition.
*/
LOCAL_FUNC void NEAR
get_btns (POINTER *p, char *options)
{
int n;
for (n = 0; n < rangeof (p->btn); ++n)
p->btn[n] = 0;
get_btn (p, options, "d=", BTN_DEBOUNCE);
get_btn (p, options, "r=", K_RLS);
get_btn (p, options, "a=", K_ALT);
get_btn (p, options, "c=", K_CTRL);
get_btn (p, options, "p=", K_SPECIAL);
get_btn (p, options, "s=", K_SHIFT);
/* remember that debounce and release have a negative logic.
*/
for (n = 0; n < rangeof (p->btn); ++n)
p->btn[n] ^= (BTN_DEBOUNCE | K_RLS);
}
/* handle a button press with debouncing.
*/
extern void FAR
do_btn (POINTER *p, int button, int state)
{
Ushort cmd[1];
if (state)
state = BTN_POSITION;
if ((BTN_POSITION & p->btn[button]) != (Ushort)state) /* toggle */
p->btn[button] ^= BTN_POSITION;
else if (BTN_DEBOUNCE & p->btn[button])
return; /* debounce */
/* do not interfere with user keystrokes.
*/
if (st.flags & SF_INTERACTIVE)
return;
if (state)
cmd[0] = 0;
else if (K_RLS & p->btn[button])
cmd[0] = K_RLS;
else
return;
cmd[0] |= K_BTN | (st.btnmode & p->btn[button] & K_MODES)
| menuch[button];
mac_interpret (cmd, rangeof (cmd));
}
extern void FAR
do_btns (POINTER *p, char *btn, int size)
{
int i;
/* button releases
*/
for (i = 0; i < size; ++i)
if (!btn[i])
do_btn (p, i, 0);
for (; i < rangeof (p->btn); ++i)
if (!(p->btn[i] & BTN_POSITION))
do_btn (p, i, 0);
/* button presses
*/
for (i = 0; i < size; ++i)
if (btn[i])
do_btn (p, i, 1);
for (; i < rangeof (p->btn); ++i)
if (p->btn[i] & BTN_POSITION)
do_btn (p, i, 1);
}
/* Set buttons mode.
*/
static MENU FAR MenuBtn[] = {
{'0', "off"},
{'1', "on"},
{'2', "toggle"},
{'a', "Alt"}, /* 3 */
{'c', "Ctrl"}, /* 4 */
{'s', "Shift"}, /* 5 */
{'p', "sPecial"}, /* 6 */
{'d', "Debounce"}, /* 7 */
{'r', "Release"}, /* 8 */
{'x', "Clear"}, /* 9 */
{'*', "Cancel"}, /* 10 */
{'\0', 0}};
extern int FAR
menu_btn (void)
{
int sel, quit, ch;
Ushort i;
int j;
HMSG *m;
POINTER *p;
if (F(p = CC->pointer))
MsgWPrintf (50, "No pointer!");
m = MsgEPrintf (0, "enter button name:");
do {
ch = mgetch ();
j = opt36 (ch);
} while (j < 0);
msg_del (m);
m = MsgEPrintf (0, "defining button %c", ch);
i = p ? p->btn[j] : 0;
SetOption (0, 2); /* default mode: toggle */
sel = 2;
for (quit = 0; !quit;) {
sel = menu_open (MenuBtn, sel);
switch (sel) {
case MENU_ABORTED:
default:
quit = 1;
break;
case 0:
case 1:
case 2:
SetOption (0, sel);
break;
case 3:
SetOption (&i, K_ALT);
break;
case 4:
SetOption (&i, K_CTRL);
break;
case 5:
SetOption (&i, K_SHIFT);
break;
case 6:
SetOption (&i, K_SPECIAL);
break;
case 7:
SetOption (&i, K_RLS);
break;
case 8:
SetOption (&i, BTN_DEBOUNCE);
break;
case 9:
i = 0;
SetOption (0, 1);
break;
case 10:
i = p ? p->btn[j] : 0;
quit = 1;
break;
}
if (MENU_FAILED != sel)
menu_close ();
}
if (p)
p->btn[j] = i;
msg_del (m);
return (0);
}
#undef NO_DEBOUNCE